<template>
  <div class="app-container" style="background-color: #ecf0f5;">
    <div style="font-size: 24px;margin-bottom:5px;"> 任务管理</div>
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item prop="jobGroup">
        <el-tag class="action_tag">执行器</el-tag>
        <el-select v-model="queryParams.jobGroup" placeholder="请选择" clearable @keyup.enter.native="handleQuery">
          <el-option v-for="item in actuator_options" :key="item.value" :label="item.label" :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="triggerStatus ">
        <el-select v-model="queryParams.triggerStatus" placeholder="请选择" style="width: 100px;" clearable
          @keyup.enter.native="handleQuery">
          <el-option v-for="item in status_options" :key="item.value" :label="item.label" :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="jobDesc">
        <el-input v-model="queryParams.jobDesc" placeholder="请输入任务描述" style="width: 200px;" clearable
          @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item prop="executorHandler">
        <el-input v-model="queryParams.executorHandler" placeholder="请输入JobHandler" clearable style="width: 200px;"
          @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item prop="author">
        <el-input v-model="queryParams.author" placeholder="请输入负责人" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>

      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" style="background-color: #3fc4f8;"
          @click="handleQuery">搜索</el-button>
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['xxl-job:info:add']" style="background-color: rgb(21, 163, 21);color: white;">新增</el-button>
      </el-form-item>
    </el-form>
    <!--select控制一个页面展示多少条-->
    <div style="background-color: #FFF;">
      <span style="margin: 5px 5px 5px 5px;">每页
        <el-select v-model="queryParams.pageSize" style="width: 80px" @change="handleSizeChange" size="small">
          <el-option default-value="10" v-for="item in pageSize_options" :key="item.value" :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
        条记录
      </span>
      <!-- 展示内容表格主体 -->
      <el-table v-loading="loading" :data="infoList" slot="empty" :max-height="getTableHeight()"
        :default-sort='{ prop: "id", order: "ascending" }'
        :header-cell-style="{ background: '#FFF', border: 'rgba(227, 227, 227, 1)' }"
        @selection-change="handleSelectionChange">
        <el-table-column label="任务ID" align="center" prop="id" />
        <el-table-column label="任务描述" align="center" prop="jobDesc" />
        <el-table-column label="调度类型" align="center" prop="scheduleType,scheduleConf">
          <template slot-scope="scope">
            {{ scope.row.scheduleType }}{{ scheduleTypeJudge(scope.row.scheduleType) }}{{ scope.row.scheduleConf }}
          </template>
        </el-table-column>>
        <el-table-column label="运行模式" align="center" prop="glueType,excutorHandler">
          <template slot-scope="scope">
            {{ glueTypeTran(scope.row.glueType) }}{{ glueTypeJudge(scope.row.glueType) }}{{ scope.row.executorHandler }}
          </template>
        </el-table-column>
        <el-table-column label="负责人" align="center" prop="author" />
        <el-table-column label="状态" align="center" prop="triggerStatus">
          <template slot-scope="scope">
            <el-tag :color="scope.row.triggerStatus === 0 ? '#d3d4d6' : 'rgb(21, 163, 21)'"
              :style="{ color: scope.row.triggerStatus === 0 ? 'black' : 'white' }"><strong>{{
                getStatus(scope.row.triggerStatus) }}</strong>
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
          <template slot-scope="scope">
            <el-button-group>
              <el-button type="small"
                style="background-color:#4b8dcb;color:white;border-color:#4b8dcb;margin-right:0px">操作</el-button>
              <el-dropdown @command="(command) => { handleCommand(command, scope.row) }">
                <el-button type="small"
                  style="background-color:#4b8dcb;color:white;border-color:#4b8dcb;margin-left:0px"><i
                    class="el-icon-caret-bottom"></i></el-button>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="run_once">执行一次</el-dropdown-item>
                  <el-dropdown-item command="search_log">查询日志</el-dropdown-item>
                  <el-dropdown-item command="signup_ip">注册节点</el-dropdown-item>
                  <el-dropdown-item command="next_runtime"
                    v-if="scope.row.scheduleType !== 'NONE'">下次执行时间</el-dropdown-item>
                  <el-dropdown-item command="glue_ide" v-if="scope.row.glueType !== 'BEAN'" divided>GLUE
                    IDE</el-dropdown-item>
                  <el-dropdown-item command="open" divided>{{ getBindStatus(scope.row.triggerStatus) }}</el-dropdown-item>
                  <el-dropdown-item command="edit" v-hasPermi="['xxl-job:info:edit']">编辑</el-dropdown-item>
                  <el-dropdown-item command="del" v-hasPermi="['xxl-job:info:remove']">删除</el-dropdown-item>
                  <el-dropdown-item command="copy">复制</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </el-button-group>
          </template>
        </el-table-column>
      </el-table>
      <!--下面展示总共条数和切换页面-->
      <el-pagination background layout="total,->,prev, pager, next" v-show="total > 0" :total="total"
        :current-page="queryParams.pageNum" :page-size="queryParams.pageSize" prev-text="上页" next-text="下页"
        @pagination="getList" @current-change="handleCurrentChange" />
    </div>

    <!-- 添加执行一次对话框 -->
    <el-dialog :title="title" :visible.sync="open_once" width="90%" append-to-body>
      <el-form ref="form_once" :model="form" :rules="rules_once" label-width="120px">
        <el-row>执行一次</el-row>
        <hr>
        <el-row :gutter="32">
          <el-col>
            <el-form-item label="任务参数" prop="executorParam">
              <el-input v-model="form.executorParam" placeholder="请输入任务参数" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="32">
          <el-col>
            <el-form-item label="机器地址" prop="addressList">
              <!-- props随手填了一个记得改-->
              <el-input v-model="addressList" placeholder="请输入本次执行的机器地址，为空则从执行器获取" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitTriggerForm">保 存</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 打开GLUE在线编辑器 -->
    <el-dialog title="GLUE IDE在线编辑器" :visible.sync="openGlue" :fullscreen="true" append-to-body>
      <GlueIde ref="glueIde" :glueCodeList="glueCodeList" :showIde="openGlue" @showChange="$event => showChange()"
        @copeChange="$event => copeChange()" />
    </el-dialog>

    <!-- 添加或修改任务管理对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="90%" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
        <el-row>基础配置</el-row>
        <hr>
        <el-row :gutter="32">
          <el-col :span="12">
            <el-form-item label="执行器" prop="jobGroup">
              <el-select v-model="form.jobGroup">
                <el-option v-for=" item  in  actuator_options " :key="item.value" :label="item.label"
                  :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="任务描述" prop="jobDesc">
              <el-input v-model="form.jobDesc" placeholder="请输入任务描述" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="32">
          <el-col :span="12">
            <el-form-item label="负责人" prop="author">
              <el-input v-model="form.author" placeholder="请输入负责人" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="报警邮件" prop="alarmEmail">
              <el-input v-model="form.alarmEmail" placeholder="请输入报警邮件，多个邮件地址则逗号分开" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>调度配置</el-row>
        <hr>
        <el-row :gutter="32">
          <el-col :span="12">
            <el-form-item label="调度类型" prop="scheduleType">
              <el-select v-model="form.scheduleType">
                <el-option label="无" value="NONE" />
                <el-option label="CRON" value="CRON" />
                <!-- <el-option label="固定速度" value="FIX_RATE" /> -->
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.scheduleType === 'CRON'">
            <el-form-item label="Cron" prop="scheduleConf">
              <template>
                <el-popover placement="bottom" trigger="click" v-model="visiblepop">
                  <el-input v-model="form.scheduleConf" placeholder="Cron表达式" slot="reference" />
                  <el-tabs type="border-card">
                    <el-tab-pane label="秒" v-if="shouldHide('second')">
                      <CrontabSecond @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
                        ref="cronsecond" />
                    </el-tab-pane>

                    <el-tab-pane label="分钟" v-if="shouldHide('min')">
                      <CrontabMin @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
                        ref="cronmin" />
                    </el-tab-pane>

                    <el-tab-pane label="小时" v-if="shouldHide('hour')">
                      <CrontabHour @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
                        ref="cronhour" />
                    </el-tab-pane>

                    <el-tab-pane label="日" v-if="shouldHide('day')">
                      <CrontabDay @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
                        ref="cronday" />
                    </el-tab-pane>

                    <el-tab-pane label="月" v-if="shouldHide('month')">
                      <CrontabMonth @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
                        ref="cronmonth" />
                    </el-tab-pane>

                    <el-tab-pane label="周" v-if="shouldHide('week')">
                      <CrontabWeek @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
                        ref="cronweek" />
                    </el-tab-pane>

                    <el-tab-pane label="年" v-if="shouldHide('year')">
                      <CrontabYear @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
                        ref="cronyear" />
                    </el-tab-pane>
                  </el-tabs>
                  <CrontabResult ref="crontabResult" :ex="crontabValueString" />
                  <div class="pop_btn">
                    <el-button type="primary" @click="submitFill">确定</el-button>
                    <el-button type="warning" @click="clearCron">重置</el-button>
                    <el-button @click="hidePop">取消</el-button>
                  </div>
                </el-popover>
              </template>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>任务配置</el-row>
        <hr>
        <el-row :gutter="32">
          <el-col :span="12">
            <el-form-item label="运行模式" prop="glueType">
              <el-select v-model="form.glueType">
                <el-option label="BEAN" value="BEAN" />
                <el-option label="GLUE(Java)" value="GLUE_GROOVY" />
                <el-option label="GLUE(Shell)" value="GLUE_SHELL" />
                <el-option label="GLUE(Python)" value="GLUE_PYTHON" />
                <el-option label="GLUE(PHP)" value="GLUE_PHP" />
                <el-option label="GLUE(Nodejs)" value="GLUE_NODEJS" />
                <el-option label="GLUE(PowerShell)" value="GLUE_POWERSHELL" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="JobHandler" prop="executorHandler" v-if="form.glueType !== 'BEAN'">
              <el-input v-model="form.executorHandler" placeholder="请输入JobHandler" maxlength="100" :disabled=true />
            </el-form-item>
            <el-form-item label="JobHandler" prop="executorHandler" v-if="form.glueType === 'BEAN'">
              <el-input v-model="form.executorHandler" placeholder="请输入JobHandler" maxlength="100" :disabled=false />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="任务参数" prop="executorParam">
          <el-input v-model="form.executorParam" placeholder="请输入任务参数" type="textarea" />
        </el-form-item>
        <el-row>高级配置</el-row>
        <hr>
        <el-row :gutter="32">
          <el-col :span="12">
            <el-form-item label="路由策略" prop="executorRouteStrategy">
              <el-select v-model="form.executorRouteStrategy">
                <el-option label="第一个" value="FIRST" />
                <el-option label="最后一个" value="LAST" />
                <el-option label="轮询" value="ROUND" />
                <el-option label="随机" value="RANDOM" />
                <el-option label="一致性HASH" value="CONSISTENT_HASH" />
                <el-option label="最不经常使用" value="LEAST_FREQUENTLY_USED" />
                <el-option label="最近最久未使用" value="LEAST_RECENTLY_USED" />
                <el-option label="故障转移" value="FAILOVER" />
                <el-option label="忙碌转移" value="BUSYOVER" />
                <el-option label="分片广播" value="SHARDING_BROADCAST" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="子任务ID" prop="childJobid">
              <el-input v-model="form.childJobid" placeholder="请输入子任务的任务ID，若存在多个则逗号分开" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="32">
          <el-col :span="12">
            <el-form-item label="调度过期策略" prop="misfireStrategy">
              <el-select v-model="form.misfireStrategy">
                <el-option label="忽略" value="DO_NOTHING" />
                <el-option label="立即执行一次" value="FIRE_ONCE_NOW" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="阻塞处理策略" prop="executorBlockStrategy">
              <el-select v-model="form.executorBlockStrategy">
                <el-option label="单机串行" value="SERIAL_EXECUTION" />
                <el-option label="丢弃后续调度" value="DISCARD_LATER" />
                <el-option label="覆盖之前调度" value="COVER_EARLY" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="32">
          <el-col :span="12">
            <el-form-item label="任务超时时间" prop="executorTimeout">
              <el-input v-model="form.executorTimeout" placeholder="任务超时时间，单位秒，大于零时生效" maxlength="6" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="失败重试次数" prop="executorFailRetryCount">
              <el-input v-model="form.executorFailRetryCount" placeholder="失败重试次数，大于零时生效" maxlength="4" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div class="dialog-footer">
        <el-button type="primary" @click="submitForm">保 存</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
  
<script>
import { listInfo, getInfo, delInfo, addInfo, updateInfo, openInfo, stopInfo, nextInfo, triggerInfo, getCodeInfo, saveCodeInfo } from "@/api/xxl-job/info";
import { listGroup } from "@/api/xxl-job/group";
import CrontabSecond from "./components/second.vue";
import CrontabMin from "./components/min.vue";
import CrontabHour from "./components/hour.vue";
import CrontabDay from "./components/day.vue";
import CrontabMonth from "./components/month.vue";
import CrontabWeek from "./components/week.vue";
import CrontabYear from "./components/year.vue";
import CrontabResult from "./components/results.vue";
import GlueIde from "./components/glueIDE.vue";

export default {
  name: "Info",
  props: ["expression", "hideComponent"],
  data() {
    // 表单校验数据类型
    const isNum = (rule, value, callback) => { // 参数顺序必须如
      let reg = /^[0-9]{1,6}$/;
      if (reg.test(value)) {
        callback()
      } else {
        callback(new Error("必须为整数"))
      }
    }
    const isEmail = (rule, value, callback) => {
      let reg = /^\w{1,18}@[a-z0-9]+(\.[a-z]{2,4})+$/i;
      if (reg.test(value)) {
        callback()
      } else if (value == null) {
        callback()
      } else {
        callback(new Error("必须符合邮箱格式"))
      }
    }

    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 任务管理表格数据
      infoList: [],
      // 获取的执行器数据
      grouplist: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      open_once: false,
      addressList: null,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        jobGroup: null,
        jobDesc: null,
        addTime: null,
        author: null,
        alarmEmail: null,
        scheduleType: null,
        scheduleConf: null,
        misfireStrategy: null,
        executorRouteStrategy: null,
        executorHandler: null,
        executorParam: null,
        executorBlockStrategy: null,
        executorTimeout: null,
        executorFailRetryCount: null,
        glueType: null,
        glueSource: null,
        glueRemark: null,
        glueUpdatetime: null,
        childJobid: null,
        triggerStatus: null,
        triggerLastTime: null,
        triggerNextTime: null
      },
      // 表单参数
      form: {},
      status_options: [
        {
          value: '',
          label: '全部'
        }, {
          value: '0',
          label: '停止'
        }, {
          value: '1',
          label: '运行'
        }],
      actuator_options: [],
      pageSize_options: [
        {
          value: 10,
          label: 10
        }, {
          value: 20,
          label: 20
        }, {
          value: 30,
          label: 30
        }, {
          value: 50,
          label: 50
        }, {
          value: 100,
          label: 100
        }],
      // 表单校验
      rules: {
        jobGroup: [
          { required: true, message: "执行器主键ID不能为空", trigger: "blur" }
        ],
        jobDesc: [
          { required: true, message: "任务描述不能为空", trigger: "blur" }
        ],
        scheduleType: [
          { required: true, message: "调度类型不能为空", trigger: "change" }
        ],
        scheduleConf: [
          { required: true, message: "CRON表达式不能为空", trigger: "blur" }
        ],
        misfireStrategy: [
          { required: true, message: "调度过期策略不能为空", trigger: "blur" }
        ],
        executorTimeout: [
          { required: true, message: "任务执行超时时间，单位秒不能为空", trigger: "blur" },
          { validator: isNum, message: "任务执行超时时间必须为正整数", trigger: 'blur' }
        ],
        executorFailRetryCount: [
          { required: true, message: "失败重试次数不能为空", trigger: "blur" },
          { validator: isNum, message: "失败重试次数必须为正整数", trigger: 'blur' }
        ],
        glueType: [
          { required: true, message: "GLUE类型不能为空", trigger: "change" }
        ],
        author: [
          { required: true, message: "负责人不能为空", trigger: "blur" }
        ],
        executorRouteStrategy: [
          { required: true, message: "路由策略不能为空", trigger: "blur" }
        ],
        executorBlockStrategy: [
          { required: true, message: "阻塞处理策略不能为空", trigger: "blur" }
        ],
        alarmEmail: [
          { validator: isEmail, message: "请输入正确的邮箱" }
        ]
      },
      rules_once: {

      },

      tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
      tabActive: 0,
      myindex: 0,
      visiblepop: false,
      openGlue: false,
      codeGlueType: null,
      codeList: {
        id: null,
        jobId: null,
        glueType: null,
        glueSource: null,
        glueRemark: null,
        addTime: null,
        updateTime: null
      },
      codeParams: {
        id: null,
        jobId: null,
        glueType: null,
        glueSource: null,
        glueRemark: null,
        addTime: null,
        updateTime: null
      },
      glueCodeList: [],
      crontabValueObj: {
        second: "*",
        min: "*",
        hour: "*",
        day: "*",
        month: "*",
        week: "?",
        year: ""
      }
    };
  },
  created() {
    this.getList();
    this.getGroup();
    this.queryParams.pageSize = this.pageSize_options[0].value;
    this.queryParams.triggerStatus = this.status_options[0].value
  },
  mount() {
    this.getGroup();
  },
  methods: {
    /** 查询任务管理列表 */
    getList() {
      this.loading = true;
      listInfo(this.queryParams).then(response => {
        this.infoList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    // 获取执行器数据
    getGroup() {
      this.loading = true;
      listGroup(this.queryParams).then(response => {
        this.groupList = response.rows;
        for (let item in this.groupList) {
          this.actuator_options.push({
            value: this.groupList[item].id,
            label: this.groupList[item].title
          })
        }
        this.queryParams.jobGroup = this.actuator_options[0].value
        this.loading = false;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.open_once = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        jobGroup: null,
        jobDesc: null,
        addTime: null,
        updateTime: null,
        author: null,
        alarmEmail: null,
        scheduleType: null,
        scheduleConf: null,
        misfireStrategy: null,
        executorRouteStrategy: null,
        executorHandler: null,
        executorParam: null,
        executorBlockStrategy: null,
        executorTimeout: null,
        executorFailRetryCount: null,
        glueType: null,
        glueSource: null,
        glueRemark: null,
        glueUpdatetime: null,
        childJobid: null,
        triggerStatus: null,
        triggerLastTime: null,
        triggerNextTime: null
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.form.glueType = 'BEAN';
      this.open = true;
      this.title = "添加任务管理";
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids
      getInfo(id).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改任务管理";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.scheduleType == 'NONE') {
            this.form.scheduleConf = null
          }
          if (this.form.id != null) {
            updateInfo(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            this.initCode();
            addInfo(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 执行一次提交按钮 */
    submitTriggerForm() {
      this.$refs["form_once"].validate(valid => {
        if (valid) {
          triggerInfo(this.form.id, this.form.executorParam, this.addressList).then(response => {
            this.open_once = false;
            this.reset();
          })
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal.confirm('是否确认删除任务管理编号为"' + ids + '"的数据项？').then(function() {
        return delInfo(ids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => { });
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('xxl-job/info/export', {
        ...this.queryParams
      }, `info_${new Date().getTime()}.xlsx`)
    },
    /**获取状态绑定数据 */
    getBindStatus(status) {
      if (status == "0") {
        status = '启动'
      }
      else {
        status = '停止'
      }
      return status
    },
    /**获取状态绑定显示参数 */
    getStatus(status) {
      if (status == "1") {
        status = 'RUNNING'
      }
      else {
        status = 'STOP'
      }
      return status
    },
    /**根据当前窗口高度动态设置el-table的显示宽度 上方200 下方60*/
    getTableHeight() {
      return (window.innerHeight - 280)
    },
    /**页面改变变化 */
    handleSizeChange(val) {
      this.queryParams.pageSize = val
      this.getList()
    },
    /**修改当前页所触发的函数*/
    handleCurrentChange(val) {
      this.queryParams.pageNum = val;
      this.getList();
    },
    /** 是否显示冒号判断*/
    glueTypeJudge(type) {
      if (type == 'BEAN') {
        return ':'
      }
      else return ''
    },
    scheduleTypeJudge(type) {
      if (type != 'NONE') {
        return ':'
      }
      else return ''
    },
    // glueTpye类型转换
    glueTypeTran(type) {
      if (type == 'BEAN') {
        return 'BEAN'
      } else if (type == 'GLUE_GROOVY') {
        return 'GLUE(Java)'
      } else if (type == 'GLUE_SHELL') {
        return 'GLUE(Shell)'
      } else if (type == 'GLUE_PYTHON') {
        return 'GLUE(Python)'
      } else if (type == 'GLUE_PHP') {
        return 'GLUE(PHP)'
      } else if (type == 'GLUE_NODEJS') {
        return 'GLUE(Nodejs)'
      } else if (type == 'GLUE_POWERSHELL') {
        return 'GLUE(PowerShell)'
      }
    },
    /** 下拉栏操作 */
    handleCommand(command, row) {
      if (command == "del") {
        const taskIds = row.id || this.ids;
        this.$modal.confirm('是否确认删除任务管理编号为"' + taskIds + '"的数据项？').then(function() {
          return delInfo(taskIds);
        }).then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        }).catch(() => { });
      }
      else if (command == "edit") {
        this.reset();
        const taskId = row.id || this.ids
        getInfo(taskId).then(response => {
          this.form = response.data;
          this.open = true;
          this.title = "修改任务管理";
        });
      }
      else if (command == "copy") {
        this.reset();
        const taskId = row.id || this.ids
        getInfo(taskId).then(response => {
          this.form = response.data;
          this.open = true;
          this.form.id = null
          this.title = "复制任务管理";
        });
      }
      else if (command == "signup_ip") {
        this.$alert("", "注册节点");
      }
      //到时候修改成调度日志的path
      else if (command == "search_log") {
        this.$router.push({ path: "/xxl-job/log/" });
      }
      else if (command == "open") {
        const taskIds = row.id || this.ids;
        if (row.triggerStatus == 0) {
          openInfo(taskIds).then(response => {
            this.getList();
          })
        }
        else {
          stopInfo(taskIds).then(response => {
            this.getList();
          })
        }
      }
      else if (command == "next_runtime") {
        const taskIds = row.id || this.ids;
        nextInfo(taskIds).then(response => {
          this.$alert(`<strong>` + response.data[0] + `<br/>` + response.data[1] + `<br/>` + response.data[2] + `<br/>` + response.data[3] + `<br/>` + response.data[4] + `</strong>`, '下次执行时间', {
            confirmButtonText: '确定',
            dangerouslyUseHTMLString: true,
            center: "true"
          })
        })
      }
      else if (command == "run_once") {
        this.reset();
        const taskIds = row.id || this.ids;
        this.form.id = taskIds
        this.open_once = true;
      }
      else if (command == 'glue_ide') {
        this.codeParams.jobId = row.id
        this.codeGlueType = row.glueType
        getCodeInfo(this.codeParams).then(response => {
          const codeLists = response.data
          if (codeLists[0] == null) {
            this.glueCodeList.push({
              jobId: this.codeParams.jobId,
              glueType: this.codeGlueType
            })
          } else {
            for (let item in codeLists) {
              this.glueCodeList.push(codeLists[item])
            }
          }
          this.openGlue = true
        })
      }
      else {
        this.$message('click on item ' + command)
      }
    },


    // 初始源码生成
    initCode() {
      if (this.form.glueType === 'GLUE_GROOVY') {
        this.form.glueSource = `
package com.xxl.job.service.handler;

import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.IJobHandler;

public class DemoGlueJobHandler extends IJobHandler {

	@Override
	public void execute() throws Exception {
		XxlJobHelper.log("XXL-JOB, Hello World.");
	}

}
        `
      } else if (this.form.glueType === 'GLUE_SHELL') {
        this.form.glueSource = `
#!/bin/bash
echo "xxl-job: hello shell"

echo "脚本位置：$0"
echo "任务参数：$1"
echo "分片序号 = $2"
echo "分片总数 = $3"

echo "Good bye!"
exit 0
        `
      } else if (this.form.glueType === 'GLUE_PYTHON') {
        this.form.glueSource = `
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import time
import sys

print "xxl-job: hello python"

print "脚本位置：", sys.argv[0]
print "任务参数：", sys.argv[1]
print "分片序号：", sys.argv[2]
print "分片总数：", sys.argv[3]

print "Good bye!"
exit(0)
        `
      } else if (this.form.glueType === 'GLUE_PHP') {
        this.form.glueSource = String.raw`
&lt?php

echo "xxl-job: hello php  \n";

echo "脚本位置：$argv[0]  \n";
echo "任务参数：$argv[1]  \n";
echo "分片序号 = $argv[2]  \n";
echo "分片总数 = $argv[3]  \n";

echo "Good bye!  \n";
exit(0);

?&gt
        `
      } else if (this.form.glueType === 'GLUE_NODEJS') {
        this.form.glueSource = `
#!/usr/bin/env node
console.log("xxl-job: hello nodejs")

var arguments = process.argv

console.log("脚本位置: " + arguments[1])
console.log("任务参数: " + arguments[2])
console.log("分片序号: " + arguments[3])
console.log("分片总数: " + arguments[4])

console.log("Good bye!")
process.exit(0)
        `
      } else if (this.form.glueType === 'GLUE_POWERSHELL') {
        this.form.glueSource = `
Write-Host "xxl-job: hello powershell"

Write-Host "脚本位置: " $MyInvocation.MyCommand.Definition
Write-Host "任务参数: "
	if ($args.Count -gt 2) { $args[0..($args.Count-3)] }
Write-Host "分片序号: " $args[$args.Count-2]
Write-Host "分片总数: " $args[$args.Count-1]

Write-Host "Good bye!"
exit 0
        `
      }
    },
    // GLUE编辑器传值
    showChange() {
      this.glueCodeList = []
      this.openGlue = this.$refs.glueIde.getShow()
    },
    copeChange() {
      this.codeList.jobId = this.codeParams.jobId
      this.codeList.glueSource = this.$refs.glueIde.getCode()
      this.codeList.glueRemark = this.$refs.glueIde.getRemark()
      const code = this.codeList.glueSource.replace(/</g, '&lt')
      this.codeList.glueSource = code.replace(/>/g, '&gt')
      saveCodeInfo(this.codeList).then(response => {
        this.$modal.msgSuccess("源码保存成功")
      })
    },


    shouldHide(key) {
      if (this.hideComponent && this.hideComponent.includes(key)) return false;
      return true;
    },
    resolveExp() {
      // 反解析 表达式
      if (this.expression) {
        let arr = this.expression.split(" ");
        if (arr.length >= 6) {
          //6 位以上是合法表达式
          let obj = {
            second: arr[0],
            min: arr[1],
            hour: arr[2],
            day: arr[3],
            month: arr[4],
            week: arr[5],
            year: arr[6] ? arr[6] : ""
          };
          this.crontabValueObj = {
            ...obj
          };
          for (let i in obj) {
            if (obj[i]) this.changeRadio(i, obj[i]);
          }
        }
      } else {
        // 没有传入的表达式 则还原
        this.clearCron();
      }
    },
    // tab切换值
    tabCheck(index) {
      this.tabActive = index;
    },
    // 由子组件触发，更改表达式组成的字段值
    updateCrontabValue(name, value, from) {
      "updateCrontabValue", name, value, from;
      this.crontabValueObj[name] = value;
      if (from && from !== name) {
        // console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
        this.changeRadio(name, value);
      }
      this.form.scheduleConf = this.valueString();
    },
    // 赋值到组件
    changeRadio(name, value) {
      let arr = ["second", "min", "hour", "month"],
        refName = "cron" + name,
        insValue;

      if (!this.$refs[refName]) return;

      if (arr.includes(name)) {
        if (value === "*") {
          insValue = 1;
        } else if (value.indexOf("-") > -1) {
          let indexArr = value.split("-");
          isNaN(indexArr[0])
            ? (this.$refs[refName].cycle01 = 0)
            : (this.$refs[refName].cycle01 = indexArr[0]);
          this.$refs[refName].cycle02 = indexArr[1];
          insValue = 2;
        } else if (value.indexOf("/") > -1) {
          let indexArr = value.split("/");
          isNaN(indexArr[0])
            ? (this.$refs[refName].average01 = 0)
            : (this.$refs[refName].average01 = indexArr[0]);
          this.$refs[refName].average02 = indexArr[1];
          insValue = 3;
        } else {
          insValue = 4;
          this.$refs[refName].checkboxList = value.split(",");
        }
      } else if (name == "day") {
        if (value === "*") {
          insValue = 1;
        } else if (value == "?") {
          insValue = 2;
        } else if (value.indexOf("-") > -1) {
          let indexArr = value.split("-");
          isNaN(indexArr[0])
            ? (this.$refs[refName].cycle01 = 0)
            : (this.$refs[refName].cycle01 = indexArr[0]);
          this.$refs[refName].cycle02 = indexArr[1];
          insValue = 3;
        } else if (value.indexOf("/") > -1) {
          let indexArr = value.split("/");
          isNaN(indexArr[0])
            ? (this.$refs[refName].average01 = 0)
            : (this.$refs[refName].average01 = indexArr[0]);
          this.$refs[refName].average02 = indexArr[1];
          insValue = 4;
        } else if (value.indexOf("W") > -1) {
          let indexArr = value.split("W");
          isNaN(indexArr[0])
            ? (this.$refs[refName].workday = 0)
            : (this.$refs[refName].workday = indexArr[0]);
          insValue = 5;
        } else if (value === "L") {
          insValue = 6;
        } else {
          this.$refs[refName].checkboxList = value.split(",");
          insValue = 7;
        }
      } else if (name == "week") {
        if (value === "*") {
          insValue = 1;
        } else if (value == "?") {
          insValue = 2;
        } else if (value.indexOf("-") > -1) {
          let indexArr = value.split("-");
          isNaN(indexArr[0])
            ? (this.$refs[refName].cycle01 = 0)
            : (this.$refs[refName].cycle01 = indexArr[0]);
          this.$refs[refName].cycle02 = indexArr[1];
          insValue = 3;
        } else if (value.indexOf("#") > -1) {
          let indexArr = value.split("#");
          isNaN(indexArr[0])
            ? (this.$refs[refName].average01 = 1)
            : (this.$refs[refName].average01 = indexArr[0]);
          this.$refs[refName].average02 = indexArr[1];
          insValue = 4;
        } else if (value.indexOf("L") > -1) {
          let indexArr = value.split("L");
          isNaN(indexArr[0])
            ? (this.$refs[refName].weekday = 1)
            : (this.$refs[refName].weekday = indexArr[0]);
          insValue = 5;
        } else {
          this.$refs[refName].checkboxList = value.split(",");
          insValue = 6;
        }
      } else if (name == "year") {
        if (value == "") {
          insValue = 1;
        } else if (value == "*") {
          insValue = 2;
        } else if (value.indexOf("-") > -1) {
          insValue = 3;
        } else if (value.indexOf("/") > -1) {
          insValue = 4;
        } else {
          this.$refs[refName].checkboxList = value.split(",");
          insValue = 5;
        }
      }
      this.$refs[refName].radioValue = insValue;
    },
    // 表单选项的子组件校验数字格式（通过-props传递）
    checkNumber(value, minLimit, maxLimit) {
      // 检查必须为整数
      value = Math.floor(value);
      if (value < minLimit) {
        value = minLimit;
      } else if (value > maxLimit) {
        value = maxLimit;
      }
      return value;
    },
    valueString() {
      let obj = this.crontabValueObj;
      let str =
        obj.second +
        " " +
        obj.min +
        " " +
        obj.hour +
        " " +
        obj.day +
        " " +
        obj.month +
        " " +
        obj.week +
        (obj.year == "" ? "" : " " + obj.year);
      return str;
    },
    // 填充表达式
    submitFill() {
      this.form.scheduleConf = this.valueString();
      this.visiblepop = false;
    },
    clearCron() {
      // 还原选择项
      ("准备还原");
      this.crontabValueObj = {
        second: "*",
        min: "*",
        hour: "*",
        day: "*",
        month: "*",
        week: "?",
        year: ""
      };
      for (let j in this.crontabValueObj) {
        this.changeRadio(j, this.crontabValueObj[j]);
      }
      this.form.scheduleConf = this.valueString();
    },
    hidePop() {
      this.visiblepop = false;
    }
  },
  computed: {
    crontabValueString: function() {
      let obj = this.crontabValueObj;
      let str =
        obj.second +
        " " +
        obj.min +
        " " +
        obj.hour +
        " " +
        obj.day +
        " " +
        obj.month +
        " " +
        obj.week +
        (obj.year == "" ? "" : " " + obj.year);
      return str;
    }
  },
  components: {
    CrontabSecond,
    CrontabMin,
    CrontabHour,
    CrontabDay,
    CrontabMonth,
    CrontabWeek,
    CrontabYear,
    CrontabResult,
    GlueIde,
  },
  watch: {
    expression: "resolveExp",
    hideComponent(value) {
      // 隐藏部分组件
    },
    visiblepop(value) {
      if (value === true) {
        this.form.scheduleConf = this.valueString();
      }
    }
  },
  mounted: function() {
    this.resolveExp();
  }
};
</script>
<style scoped>
.pop_btn {
  text-align: center;
  margin-top: 20px;
}
</style>
<style>
.el-popover {
  height: 400px;
  overflow: auto;
}

.dialog-footer {
  position: sticky;
  bottom: 10px;
  text-align: center;
  background-color: #fff;
}

.el-pager li.active {
  background-color: #4b8dcb !important;
}

.action_tag {
  color: #000;
  border-radius: 0 !important;
  border-color: #d2d6de !important;
  background-color: #fff !important;
  font-size: 13px;
  height: 100%;
  line-height: 32px;
}

::v-deep .el-select .el-input__inner {
  border-radius: 0px;
}
</style>